Convolutions with various kernels
xxxxxxxxxx4
1
begin2
large_image = load("philip.jpg")3
image = shrink_image(large_image, 7)4
end3675
2988
xxxxxxxxxx1
1
size(large_image)524
425
xxxxxxxxxx1
1
size(image)9×9 OffsetArray(::Array{Float64,2}, -4:4, -4:4) with eltype Float64 with indices -4:4×-4:4:
0.0007634473286087527 0.001831414934844717 … 0.0007634473286087527
0.001831414934844717 0.004393336040201354 0.001831414934844717
0.00342153354840464 0.008207832296747467 0.00342153354840464
0.004978301937756901 0.011942325524393557 0.004978301937756901
0.005641155139668816 0.013532427693987034 0.005641155139668816
0.004978301937756901 0.011942325524393557 … 0.004978301937756901
0.00342153354840464 0.008207832296747467 0.00342153354840464
0.001831414934844717 0.004393336040201354 0.001831414934844717
0.0007634473286087527 0.001831414934844717 0.0007634473286087527xxxxxxxxxx1
1
kernel = Kernel.gaussian((2, 2))xxxxxxxxxx1
1
show_colored_kernel(kernel)1.0000000000000004xxxxxxxxxx1
1
sum(kernel)3×3 OffsetArray(::Array{Float64,2}, -1:1, -1:1) with eltype Float64 with indices -1:1×-1:1:
-0.5 -1.0 -0.5
-1.0 7.0 -1.0
-0.5 -1.0 -0.5xxxxxxxxxx4
1
kernel_sharp = centered([2
-0.5 -1.0 -0.53
-1.0 7.0 -1.04
-0.5 -1.0 -0.5])xxxxxxxxxx1
1
sharp_image = convolve(image, kernel_sharp)1.0xxxxxxxxxx1
1
sum(kernel_sharp)xxxxxxxxxx1
1
heatmap_2d_fourier_spectrum(sharp_image)xxxxxxxxxx1
1
imagexxxxxxxxxx1
1
heatmap_2d_fourier_spectrum(image)xxxxxxxxxx1
1
conv_image = convolve(image, kernel)xxxxxxxxxx1
1
heatmap_2d_fourier_spectrum(conv_image)Sobel
3×3 OffsetArray(::Array{Float64,2}, -1:1, -1:1) with eltype Float64 with indices -1:1×-1:1:
-0.125 0.0 0.125
-0.25 0.0 0.25
-0.125 0.0 0.125xxxxxxxxxx1
1
kernel_sobel = Kernel.sobel()[2]xxxxxxxxxx1
1
show_colored_kernel(kernel_sobel)0.0xxxxxxxxxx1
1
sum(kernel_sobel)xxxxxxxxxx1
1
3 * Gray.(abs.(convolve(image, kernel_sobel)))Zebra
xxxxxxxxxx4
1
begin2
big_zebra = load("zebra.jpg")3
zebra = shrink_image(big_zebra, 7)4
endxxxxxxxxxx1
1
plot_1d_fourier_spectrum(zebra)xxxxxxxxxx1
1
heatmap_2d_fourier_spectrum(zebra)9×9 OffsetArray(::Array{Float64,2}, -4:4, -4:4) with eltype Float64 with indices -4:4×-4:4:
0.0007634473286087527 0.001831414934844717 … 0.0007634473286087527
0.001831414934844717 0.004393336040201354 0.001831414934844717
0.00342153354840464 0.008207832296747467 0.00342153354840464
0.004978301937756901 0.011942325524393557 0.004978301937756901
0.005641155139668816 0.013532427693987034 0.005641155139668816
0.004978301937756901 0.011942325524393557 … 0.004978301937756901
0.00342153354840464 0.008207832296747467 0.00342153354840464
0.001831414934844717 0.004393336040201354 0.001831414934844717
0.0007634473286087527 0.001831414934844717 0.0007634473286087527xxxxxxxxxx1
1
zebra_kernel = Kernel.gaussian((2, 2))xxxxxxxxxx1
1
conv_zebra = convolve(zebra, zebra_kernel)xxxxxxxxxx1
1
plot_1d_fourier_spectrum(conv_zebra)xxxxxxxxxx1
1
heatmap_2d_fourier_spectrum(conv_zebra)Function definitions
xxxxxxxxxx9
1
begin2
using Statistics3
using Images4
using FFTW5
using Plots6
using DSP7
using ImageFiltering8
using PlutoUI9
endshow_colored_kernel (generic function with 1 method)xxxxxxxxxx4
1
function show_colored_kernel(kernel)2
to_rgb(x) = RGB(max(-x, 0), max(x, 0), 0)3
to_rgb.(kernel) / maximum(abs.(kernel))4
enddecimate (generic function with 2 methods)xxxxxxxxxx3
1
function decimate(arr, ratio=5)2
return arr[1:ratio:end, 1:ratio:end]3
endshrink_image (generic function with 2 methods)xxxxxxxxxx14
1
function shrink_image(image, ratio=5)2
(height, width) = size(image)3
new_height = height ÷ ratio - 14
new_width = width ÷ ratio - 15
list = [6
mean(image[7
ratio * i:ratio * (i + 1),8
ratio * j:ratio * (j + 1),9
])10
for j in 1:new_width11
for i in 1:new_height12
]13
reshape(list, new_height, new_width)14
endrgb_to_float (generic function with 1 method)xxxxxxxxxx3
1
function rgb_to_float(color)2
return mean([color.r, color.g, color.b])3
endfourier_spectrum_magnitudes (generic function with 1 method)xxxxxxxxxx5
1
function fourier_spectrum_magnitudes(img)2
grey_values = rgb_to_float.(img)3
spectrum = fftshift(fft(grey_values))4
return abs.(spectrum)5
endplot_1d_fourier_spectrum (generic function with 2 methods)xxxxxxxxxx4
1
function plot_1d_fourier_spectrum(img, dims=1)2
spectrum = fourier_spectrum_magnitudes(img)3
plot(centered(mean(spectrum, dims=1)[1:end]))4
endheatmap_2d_fourier_spectrum (generic function with 1 method)xxxxxxxxxx3
1
function heatmap_2d_fourier_spectrum(img)2
heatmap(log.(fourier_spectrum_magnitudes(img)))3
endclamp_at_boundary (generic function with 1 method)xxxxxxxxxx6
1
function clamp_at_boundary(M, i, j)2
return M[3
clamp(i, 1, size(M, 1)),4
clamp(j, 1, size(M, 2)), 5
]6
endrolloff_boundary (generic function with 1 method)xxxxxxxxxx7
1
function rolloff_boundary(M, i, j)2
if (1 ≤ i ≤ size(M, 1)) && (1 ≤ j ≤ size(M, 2))3
return M[i, j]4
else5
return 0 * M[1, 1]6
end7
endconvolve (generic function with 2 methods)xxxxxxxxxx23
1
function convolve(M, kernel, M_index_func=clamp_at_boundary)2
height = size(kernel, 1)3
width = size(kernel, 2)4
5
half_height = height ÷ 26
half_width = width ÷ 27
8
new_image = similar(M)9
10
# (i, j) loop over the original image11
for i in 1:size(M, 1)12
for j in 1:size(M, 2)13
# (k, l) loop over the neighbouring pixels14
new_image[i, j] = sum([15
kernel[k, l] * M_index_func(M, i - k, j - l)16
for k in -half_height:-half_height + height - 117
for l in -half_width:-half_width + width - 118
])19
end20
end21
22
return new_image23
endbox_blur (generic function with 1 method)xxxxxxxxxx1
1
box_blur(n) = centered(ones(n, n) ./ (n^2))gauss_blur (generic function with 2 methods)xxxxxxxxxx4
1
function gauss_blur(n, sigma=0.25)2
kern = gaussian((n, n), sigma)3
return kern / sum(kern)4
end